package inabit.inference;

import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;

import inabit.base.RuleBase;
import inabit.base.WorkingMemory;
import inabit.data.Rule;
import inabit.data.expression.ConsequentExpression;

import javax.swing.tree.DefaultTreeModel;
/**This class represents a generic inference engine which can retrieve and modify data
 * from RuleBase and WorkingMemory
 * @see inabit.base.RuleBase
 * @see inabit.base.WorkingMemory
 * @author Rafael Rocha*/
public abstract class InferenceEngine {
	public abstract void inference(RuleBase rb, WorkingMemory wm) throws Exception;
	public abstract DefaultTreeModel getTraceTreeModel();
	public abstract InferenceNode getTraceRoot();
	
	/**Returns a list of strings representing the inference tree*/
	public List<String> getTraceStringList(InferenceNode node) {
		List<String> traceString = new ArrayList<String>();
		traceString.add(node.getContent().toString());
		for(int i = 0; i < node.getChildCount(); i++) {
			traceString.addAll(getTraceStringList((InferenceNode)node.getChildAt(i)));
		}
		return traceString;
	}

	/**Returns the children of the node passed by parameter with the specified content*/
	protected InferenceNode getNode(InferenceNode root, String content) {
		if (root.isLeaf()) {
			if (content.equals(root.getContent())) {
				return root;
			} else {
				return null;
			}
		}

		Enumeration<InferenceNode> e = root.children();
		while (e.hasMoreElements()) {
			InferenceNode element = e.nextElement();
			if(element == null || content == null) {
				return null;
			}
			if (element.getContent().equals(content)) {
				return element;
			}
		}
		e = root.children();
		while (e.hasMoreElements()) {
			InferenceNode childNode = null;
			InferenceNode element = e.nextElement();
			childNode = getNode(element, content);
			if (childNode != null) {
				return childNode;
			}
		}
		return null;
	}
}
